package com.arquitectonic.server.persistencia.rol;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ParserRoles {

	
	// Etiquetas XML :
	private  final String TAG_ROL = "Rol";
	private  final String TAG_TIPO = "TipoVista";

	private  List<String> tiposVistas = new LinkedList<String>();
	private  Hashtable<String, Rol> rolesHash = new Hashtable<String, Rol>();

	private static ParserRoles instancia = null;
	
	
	public static ParserRoles getInstance(ServletContext context){
		
		if(instancia == null)
			instancia = new ParserRoles();
			instancia.init(context);
		return instancia;

	}
	
	public ParserRoles(){};
	
	public  void init(ServletContext context) {
		Document doc = null;
		
		tiposVistas = new LinkedList<String>();
		rolesHash = new Hashtable<String, Rol>();
		
		tiposVistas.add("N/A");
		InputStream rolesXML = context.getResourceAsStream("/WEB-INF/Roles.xml");

		try {
			
			// Create a builder factory
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();

			// Create the builder and parse the file
			doc = factory.newDocumentBuilder().parse( rolesXML
					);
			

			
		
		} catch (SAXException e) {

			System.out.println(e.getMessage());
			
		} catch (ParserConfigurationException e) {

			System.out.println(e.getMessage());
			
		} catch (IOException e) {
			
			System.out.println("Error leyendo Roles.xml");

		} 
		

		Element root = doc.getDocumentElement();

		NodeList children = root.getElementsByTagName(TAG_ROL);

		for (int i = 0; i < children.getLength(); i++) {

			LinkedList<NivelDeseadoStakeholder> nivelesDeseados = new LinkedList<NivelDeseadoStakeholder>();

			Rol rol;

			Element rolElement = (Element) children.item(i);

			NodeList tipos = rolElement.getElementsByTagName(TAG_TIPO);

			for (int j = 0; j < tipos.getLength(); j++) {

				Element tipo = (Element) tipos.item(j);
				
				String idTipo = tipo.getAttribute("id");
				
				if(!tiposVistas.contains(idTipo)){
					tiposVistas.add(idTipo);
				}
				
				nivelesDeseados.add(new NivelDeseadoStakeholder(idTipo,
						Integer.parseInt(tipo.getAttribute("nivelDeseado"))));

			}

			rol = new Rol(rolElement.getAttribute("id"), nivelesDeseados);

			rolesHash.put(rol.getNombre(), rol);

		}
		
	}

	public  String[] getRoles() {

		Set<String> roles = rolesHash.keySet();
		return setToStringArray(roles);
	}
	
	private  String[] setToStringArray(Set<String> s){
		
		String resultado[] = new String[s.size()];
		int posicion=0;
		for (String r : s) {
			
			resultado[posicion] = r;
			posicion++;

		}
		
		return resultado;
	}
	
	public  String[] getTiposVistas() {
		String[] resultado = new String[tiposVistas.size()];
		int i = 0;
		for(String vista : tiposVistas){
			resultado[i] = vista;
			i++;
		}
		
		return resultado;
		
	}

	public  ArrayList<Rol> getRoles(String roles) throws RuntimeException {

		if(roles == null || roles.equals("")){
			return new ArrayList<Rol>(0);
		}
		String[] elementos = roles.split(",");

		ArrayList<Rol> resultado = new ArrayList<Rol>();

		for (int i = 0; i < elementos.length; i++) {

			Rol auxRol = rolesHash.get(elementos[i]);

			if (auxRol == null) {
				throw new RuntimeException("Error: No se encontro el rol: "
						+ elementos[i]);
			} else {
				resultado.add(auxRol);
			}

		}

		return resultado;

	}

}